package com.think.db.mongo;

import com.think.utils.objects.Returnable;
import io.netty.util.concurrent.FastThreadLocalThread;
import lombok.Getter;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public final class DatabaseHelper {
    @Getter
    private static final ExecutorService eventExecutor =
            new ThreadPoolExecutor(
                    6,
                    6,
                    60,
                    TimeUnit.SECONDS,
                    new LinkedBlockingDeque<>(),
                    FastThreadLocalThread::new,
                    new ThreadPoolExecutor.AbortPolicy());

    public static void saveGameAsync(Object obj) {
        DatabaseHelper.eventExecutor.submit(() -> saveGameSync(obj));
    }

    public static void saveGameSync(Object obj) {
        DatabaseManager.getGameDatastore().save(obj);
    }

    public static void asyncOperations(Runnable task) {
        DatabaseHelper.eventExecutor.submit(task);
    }

    public static <T> CompletableFuture<T> fetchAsync(Returnable<T> task) {
        var future = new CompletableFuture<T>();

        DatabaseHelper.eventExecutor.submit(() -> {
            try {
                future.complete(task.invoke());
            } catch (Exception e) {
                future.completeExceptionally(e);
            }
        });

        return future;
    }

    public static synchronized void shutdown() {
        try {
            if (!eventExecutor.isTerminated()) {
                eventExecutor.awaitTermination(5, TimeUnit.SECONDS);
            }
        } catch (Exception ignored) {
        }
    }
}
